//
//  DetailViewController.swift
//  Reader
//
//  Created by wsg on 2019/10/12.
//  Copyright © 2019 codeguesser. All rights reserved.
//

import UIKit
import SwiftyJSON
import MagicalRecord
import MediaPlayer
import AVKit
import Kanna

class DetailViewController: UIViewController,AVSpeechSynthesizerDelegate {
    @IBOutlet var toolBar: UIToolbar!
    @IBOutlet var titleLabel: UILabel!
    @IBOutlet weak var pageLabel: UILabel!
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet var butteryLabel: UILabel!
    @IBOutlet var readItem: UIBarButtonItem!
    @IBOutlet var timItem: UIBarButtonItem!
    @IBOutlet weak var backgroundImageView: UIImageView!
    @IBOutlet weak var speedItem: UIBarButtonItem!
    
    var speaker:AVSpeechSynthesizer?{
        didSet{
            if self.speaker != nil{
                readItem.image = UIImage(named: "listenStoped.png")
            }else{
                readItem.image = UIImage(named: "listen.png")
            }
        }
    }
    /// 音乐、读书、不可以做任何事
    var isSpeakerReading:Bool? = nil{
        didSet{
            (UIApplication.shared.delegate as? AppDelegate)?.isRuningSpeaking = isSpeakerReading
        }
    }
    var player = AVQueuePlayer()
    
    var pageToEnd:Int?{
        didSet{
            if let end = self.pageToEnd{
                timItem.title = "\(end)"
                timItem.image = nil
            }else{
                timItem.image = UIImage(named: "timer.png")
                timItem.title = nil
            }
        }
    }
    
    var textChangedAction:(String)->Void = {_ in}
    var data:JSON?
    var strings:[String] = []
    var currentPage = 0{
        didSet{
            if self.currentPage >= self.strings.count{
                self.currentPage = self.strings.count
            }
            readLabel.text = strings[currentPage]
            UIDevice.current.isBatteryMonitoringEnabled = true
            butteryLabel.text = "🔋\((UIDevice.current.batteryLevel*100).to2fDescription.noneZeroString())%"
            UIDevice.current.isBatteryMonitoringEnabled = false
            timeLabel.text = DateFormatter(string: "HH:mm").string(from: Date())
            pageLabel.text = "第\(currentPage+1)/\(strings.count)页"
            recordReadProcess()
            
        }
    }
    @IBOutlet var readLabel: ReadLabel!
    //MARK: - system methods
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        
        NotificationCenter.default.addObserver(self, selector: #selector(changeState), name: .togglePlayPauseCommand, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(changeToNextPage), name: .playNextCommand, object: nil)
        
        //这tm的是个线控，不是外面的那个
        MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            NotificationCenter.default.post(name: .playNextCommand, object: event)
            return .success
        }
        MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            NotificationCenter.default.post(name: .togglePlayPauseCommand, object: event)
            return .success
        }
        MPRemoteCommandCenter.shared().playCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            NotificationCenter.default.post(name: .togglePlayPauseCommand, object: event)
            return .success
        }
        MPRemoteCommandCenter.shared().pauseCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in
            NotificationCenter.default.post(name: .togglePlayPauseCommand, object: event)
            return .success
        }
//        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(stopListen))
//        longPress.minimumPressDuration = 2
//        self.view.addGestureRecognizer(longPress)
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(screenTaped(tap:)))
        self.view.addGestureRecognizer(tap)
        self.speedItem.title = Preference.speed
        
        NotificationCenter.default.addObserver(self, selector: #selector(interrupt(no:)), name: AVAudioSession.interruptionNotification, object: nil)
        
        if let bg = Preference.background,bg.isNotEmptyOrBlank{
            if let img = UIImage(named: bg){
                backgroundImageView.image = img
            }else{
                if let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .allDomainsMask, true).first {
                    let rBg = dir + "/" + bg
                    if FileManager.default.isReadableFile(atPath: rBg) {
                        backgroundImageView.image = UIImage(contentsOfFile: rBg)
                    }
                }
            }
        }
    }
    @objc func interrupt(no:Notification) {
        
        if let o = no.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt{
            if o == AVAudioSession.InterruptionType.began.rawValue,let s = self.speaker,s.isSpeaking {
                s.pauseSpeaking(at: .immediate)
            }else if o == AVAudioSession.InterruptionType.ended.rawValue,let s = self.speaker,s.isPaused{
                s.continueSpeaking()
            }
        }
    }
    @objc func screenTaped(tap:UITapGestureRecognizer) {
        if self.strings.isEmpty {
            selectChapter()
            return
        }
        if !self.toolBar.isHidden{
            hideToolView()
            return
        }
        func nextPage(){
            if self.currentPage + 1 <= self.strings.count-1{
                self.currentPage = self.currentPage + 1
            }else{
                changeToNextChapter { }
            }
        }
        let point = tap.location(in: self.view)
        if point.y < 100 {
            if point.x < self.view.bounds.width/3{
                self.currentPage = max(self.currentPage-1,0)
                realStopListen()
            }else if point.x >= self.view.bounds.width/3,point.x < self.view.bounds.width/3*2{
                showToolView()
            }else{
                nextPage()
                realStopListen()
            }
        }else{
            nextPage()
            realStopListen()
        }
    }
    override var prefersStatusBarHidden: Bool{
        return true
    }
    
    //MARK: - custom methods
//    @objc func stopListen(longPress:UILongPressGestureRecognizer){
//        if longPress.state == .began {
//            realStopListen()
//        }
//    }
    func recordReadProcess(){
        MagicalRecord.save(blockAndWait: {[weak self] (context) in
            if let SSelf = self,let d = SSelf.data{
                var read = ReadModel.mr_findFirst(with: NSPredicate(format: "bid == '\(d["bid"].stringValue)' and cid == '\(d["id"].stringValue)'", argumentArray: nil),in: context)
                if read == nil{
                    read = ReadModel.mr_createEntity(in: context)
                }
                read?.bid = d["bid"].int64Value
                read?.cid = d["id"].int64Value
                read?.page = Int64(SSelf.currentPage)
                read?.total = Int64(SSelf.strings.count)
                read?.time = Date()
                if SSelf.speaker != nil {
                    read?.sound = "true"
                }
            }
        })
    }
    @IBAction func changeSpeed(_ sender: Any) {
        let alert = UIAlertController(title: "改变语速", message: "", preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "默认", style: .default, handler: { [weak self](action) in
            if let SSelf = self{
                SSelf.speedItem.title = "1"
                Preference.speed = "1"
                SSelf.realStopListen()
            }
        }))
        alert.addAction(UIAlertAction(title: "1.25倍", style: .default, handler: { [weak self](action) in
            if let SSelf = self{
                SSelf.speedItem.title = "1.25"
                Preference.speed = "1.25"
                SSelf.realStopListen()
            }
        }))
        alert.addAction(UIAlertAction(title: "1.5倍", style: .default, handler: { [weak self](action) in
            if let SSelf = self{
                SSelf.speedItem.title = "1.5"
                Preference.speed = "1.5"
                SSelf.realStopListen()
            }
        }))
        alert.addAction(UIAlertAction(title: "1.75倍", style: .default, handler: { [weak self](action) in
            if let SSelf = self{
                SSelf.speedItem.title = "1.75"
                Preference.speed = "1.75"
                SSelf.realStopListen()
            }
        }))
        alert.addAction(UIAlertAction(title: "2倍", style: .default, handler: { [weak self](action) in
            if let SSelf = self{
                SSelf.speedItem.title = "2"
                Preference.speed = "2"
                SSelf.realStopListen()
            }
        }))
        alert.addAction(UIAlertAction(title: "取消", style: .default, handler: { (action) in
        }))
        self.present(alert, animated: true, completion: nil)
    }
    func realStopListen(){
        if let s = self.speaker{
            isSpeakerReading = nil
            s.stopSpeaking(at: AVSpeechBoundary.immediate)
            self.speaker = nil
            self.pageToEnd = nil
            
            self.player.pause()
            self.player.removeAllItems()
        }
    }
    @objc func changeState(){
        if let listenThing = self.isSpeakerReading{
            if listenThing{
                readBook()
            }else{
                listenMusic()
            }
        }
    }
    @objc func changeToNextPage(){
        if self.strings.isEmpty {
            selectChapter()
            return
        }
        if !self.toolBar.isHidden{
            hideToolView()
            return
        }
        func nextPage(){
            if self.currentPage + 1 <= self.strings.count-1{
                self.currentPage = self.currentPage + 1
            }else{
                changeToNextChapter { }
            }
        }
        nextPage()
        realStopListen()
        readBook()
    }
    func resizeTexts() {
        if let d = self.data{
            self.strings = ReadLabel.crackedText(self.readLabel.bounds.size, d["text"].stringValue)
            self.titleLabel.text = d["title"].stringValue
            if let read = ReadModel.mr_findFirst(with: NSPredicate(format: "bid == '\(d["bid"].stringValue)' and cid == '\(d["id"].stringValue)'", argumentArray: nil)){
                self.currentPage = Int(read.page)
            }else{
                self.currentPage = 0
            }
        }
    }
    func showToolView()  {
        toolBar.isHidden = false
    }
    func hideToolView()  {
        toolBar.isHidden = true
    }
    @IBAction func selectChapter(){
        realStopListen()
        self.dismiss(animated: true, completion: nil)
    }
    @IBAction func listenMusic(){
        isSpeakerReading = false
        if #available(iOS 10.0, *) {
            if player.timeControlStatus == .paused{
                if player.items().isEmpty{
                    if MPMediaLibrary.authorizationStatus() == .notDetermined {
                        MPMediaLibrary.requestAuthorization({ (status) in
                            if status == .authorized {
                                for song in MPMediaQuery().items!.sorted(by: { (item1, item2) -> Bool in
                                    return Int(arc4random()) % 2 == 0
                                }){
                                    self.player.insert(AVPlayerItem(url: song.assetURL!), after: nil)
                                }
                            }else{
                                UIAlertController.alertMessage("音乐受限")
                            }
                        })
                    }else if MPMediaLibrary.authorizationStatus() == .authorized  {
                        // Fallback on earlier versions
                        
                        for song in MPMediaQuery().items!.sorted(by: { (item1, item2) -> Bool in
                            return Int(arc4random()) % 2 == 0
                        }){
                            self.player.insert(AVPlayerItem(url: song.assetURL!), after: nil)
                        }
                    }else{
                        UIAlertController.alertMessage("音乐受限")
                    }
                }
                player.play()
            }else if player.timeControlStatus == .playing{
                player.pause()
                self.player.removeAllItems()
            }
        } else {
            // Fallback on earlier versions
        }
    }
    @IBAction func readBook(){
        isSpeakerReading = true
        if let s = self.speaker{
            if s.isSpeaking{
                if s.isPaused {
                    s.continueSpeaking()
                    readItem.image = UIImage(named: "listenStoped.png")
                }else{
                    s.pauseSpeaking(at: .immediate)
                    readItem.image = UIImage(named: "listen.png")
                }
            }
        }else{
            if let t = readLabel.text,t.isNotEmpty{
                self.speaker = AVSpeechSynthesizer()
                self.speaker?.delegate = self
                let speechString = AVSpeechUtterance(string: t)
                speechString.voice = AVSpeechSynthesisVoice(language: "zh-CN")
                speechString.rate = speedItem.title == "1" ? AVSpeechUtteranceDefaultSpeechRate : ((Float(speedItem.title ?? "1") ?? 1) - 1) / 5.0 + 0.5
                self.speaker?.speak(speechString)
            }
        }
    }
    @IBAction func timerStoped(){
        func alertMessage(str :String){
            let alert = UIAlertController(title: str, message: nil, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "好的", style: .default, handler: { _ in
            }))
            self.present(alert, animated: true, completion: nil)
        }
        guard isSpeakerReading == true else {
            alertMessage(str: "阅读状态下才可以定时")
            return
        }
        if pageToEnd == nil{
            let alert = UIAlertController(title: "阅读定时关闭", message: nil, preferredStyle: .actionSheet)
            alert.addAction(UIAlertAction(title: "读10页后关闭", style: .default, handler: {[weak self] _ in
                if let SSelf = self{
                    SSelf.pageToEnd = 10
                    alertMessage(str: "读\(SSelf.pageToEnd ?? 0)页后停止")
                }
            }))
            alert.addAction(UIAlertAction(title: "读50页后关闭", style: .default, handler: {[weak self] _ in
                if let SSelf = self{
                    SSelf.pageToEnd = 50
                    alertMessage(str: "读\(SSelf.pageToEnd ?? 0)页后停止")
                }
            }))
            alert.addAction(UIAlertAction(title: "取消", style: .default, handler: { _ in
            }))
            self.present(alert, animated: true, completion: nil)
        }else{
            pageToEnd = nil
            alertMessage(str: "已取消")
        }
    }
    @IBAction func redownload(){
        RD.request(data?["url"].stringValue ?? "").responseData {[weak self] (response) in
            if let SSelf = self{
                if let d = response.value{
                    let htmlContent = SSelf.filterContent(html: d.gb2312String.replacingOccurrences(of: "\r\n", with: "\n"), keyWord: "content").htmlToString
                    SSelf.data?["text"].string = htmlContent
                    NotificationCenter.default.post(name: .newChapterDownloaded, object: ["url":SSelf.data?["url"].stringValue ?? "","content":htmlContent])
                    SSelf.resizeTexts()
                }
            }
        }
    }
    func filterContent(html:String,keyWord:String)->String {
        if let doc = try? HTML(html: html, encoding: .utf8){
            let nodes:[String] = doc.body?.xpath("//div[@id='\(keyWord)']", namespaces: nil).compactMap({$0.innerHTML}) ?? []
            if let s = nodes.sorted(by: {$0.count > $1.count}).first {
                return s
            }
        }
        return html
    }
    func changeToNextChapter( completion:@escaping ()->Void) {
        if let d = data{
            let nextId = d["id"].intValue + 1
            if let newChapter = ChapterModel.model([d["bid"].stringValue,"\(nextId)"]){
                self.data = newChapter.json
                if newChapter.text.isNotEmpty{
                    self.resizeTexts()
                    completion()
                }else{
                    RD.request(newChapter.url ?? "").responseData {[weak self] (response) in
                        if let SSelf = self{
                            if let d = response.value{
                                let htmlContent = SSelf.filterContent(html: d.gb2312String.replacingOccurrences(of: "\r\n", with: "\n"), keyWord: "content").htmlToString
                                SSelf.data?["text"].string = htmlContent
                                NotificationCenter.default.post(name: .newChapterDownloaded, object: ["url":SSelf.data?["url"].stringValue ?? "","content":htmlContent])
                                SSelf.resizeTexts()
                                completion()
                            }
                        }
                    }
                }
            }else{
                let alert = UIAlertController(title: "已经全部阅读完毕", message: nil, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "好的", style: .default, handler: { [weak self](_) in
                    if let SSelf = self{
                        SSelf.selectChapter()
                    }
                }))
                self.present(alert, animated: true, completion: nil)
            }
            
        }
    }
    //MAKR: ABOUT SPEAKER SELECTOR
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        isSpeakerReading = nil
        self.speaker = nil
        
        if let end = pageToEnd{
            if end <= 0{
                pageToEnd = nil
                return
            }
            pageToEnd = end - 1
        }
        if self.currentPage + 1 <= self.strings.count - 1 {
            self.currentPage = min(self.currentPage+1,self.strings.count-1)
            readBook()
        }else{
            changeToNextChapter { [weak self] in
                if let SSelf = self {
                    SSelf.readBook()
                }
            }
        }
    }
    @IBAction func gotoLink(_ sender: Any) {
        self.dismiss(animated: true) {[weak self] in
            if let SSelf = self,let pvc = (UIApplication.shared.windows.first?.rootViewController as? UINavigationController){
                let vc = WebViewController()
                vc.link = URL(string: SSelf.data?["url"].stringValue ?? "")
                pvc.pushViewController(vc, animated: true)
            }
        }
    }
}
